package com.ttctracker.map;

import java.util.ArrayList;
import java.util.List;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.skyhookwireless.wps.WPSLocation;
import com.ttctracker.R;
import com.ttctracker.classes.Route;
import com.ttctracker.classes.StopItem;

import com.ttctracker.map.RouteMapItemizedOverlay;
import com.ttctracker.map.RouteMapStopOverlayItem;
import com.ttctracker.map.SkyHookHelper;
import com.ttctracker.util.SqlAdapter;

import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;

public class GetNearByRoutesTask extends Handler {
	//private Handler handler;
	private SkyHookHelper skyHookHelper;
	private Context context;
	//private MyWPSLocationCallback locationCallback;
	private GeoPoint userLocation;
	private Drawable locationMarker;
	private RouteMapItemizedOverlay itemizedOverlay;
	private List<Overlay> mapOverlays;
	private MapController mController;
	private MapView mapView;
	private ProgressDialog dialog;
	private WPSLocation location; 
	private static final int SEARCH_NEARBY_CALLBACK_MESSAGE=5;
	//protected static boolean stopAccquiringGPS=false;
	
	public GetNearByRoutesTask(Context context,MapView mView, RouteMapItemizedOverlay itemizedOverlay) {

		
		this.context = context;
		this.mapView=mView;
		this.mController=mapView.getController();
		this.itemizedOverlay=itemizedOverlay;
		locationMarker = context.getResources().getDrawable(R.drawable.ic_gps);
		locationMarker.setBounds(0, 0, locationMarker.getIntrinsicWidth(),
				locationMarker.getIntrinsicHeight());

		
		mapOverlays=mapView.getOverlays();
		skyHookHelper=new SkyHookHelper(this.context,this);
		//setUIHandler();

	}
	
	public void performSearch() {
		onPreExecute();
		skyHookHelper.getUserLocation();
	}
	
	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
		case SkyHookHelper.LOCATION_MESSAGE:
				location=(WPSLocation)msg.obj;
				GeoPoint gp=new GeoPoint((int)(location.getLatitude()*1e6), (int)(location.getLongitude()*1e6));
				updateUserLocationOverlay(gp);
				//searchNearbyRoutes(location);
			break;
		case SkyHookHelper.ERROR_MESSAGE:
			break;
		case SkyHookHelper.FIRST_TIME_MESSAGE:
			location=(WPSLocation)msg.obj;
			
			new Thread(){
				public void run() {
					ArrayList<Route> searchResult=searchNearbyRoutes(location);
					GetNearByRoutesTask.this.sendMessage(GetNearByRoutesTask.this.obtainMessage(SEARCH_NEARBY_CALLBACK_MESSAGE, searchResult));
				}
			}.start();
			
			break;
		case SEARCH_NEARBY_CALLBACK_MESSAGE:
			Object result=msg.obj;
			ArrayList<Route> searchRoutes=null;
			if (result!=null) {
				searchRoutes=(ArrayList<Route>)result;
			}
			onPostExecute(searchRoutes);
			
			break;
		}
	}

	public void stopGPS() {
		skyHookHelper.toggleGPS(true);
	}
	
	public void startGPS() {
		skyHookHelper.toggleGPS(false);
	}
	
	protected void onPreExecute() {
		dialog=new ProgressDialog(context);
		dialog.setMessage("Getting GPS Location, please wait...");
		dialog.show();
	}

	protected ArrayList<Route> searchNearbyRoutes(WPSLocation location) {
		//Log.v("location",location.toString());
		
		if (location!=null) {
			double userLat = location.getLatitude();
			double userLon = location.getLongitude();
			// get coordinates
			int lat = (int) (userLat * 1E6);
			int lng = (int) (userLon * 1E6);
			GeoPoint point = new GeoPoint(lat, lng);
			userLocation = point;
			SqlAdapter adapter = new SqlAdapter(context);
			adapter.openDB();
			// String resultsString="";
			if (adapter.isOpen()) {
				ArrayList<Route> nearByRoutes = adapter.getNearByRoutes(userLat,
						userLon);
	
				adapter.close();
				//Log.v("userLocation",userLocation.toString());
				return nearByRoutes;
			}
			
		}
		

		return null;
	}

	private void updateUserLocationOverlay(GeoPoint userLocation) {
		// if (dialog.isShowing()) {

		// create overlay
		OverlayItem overlay = new OverlayItem(userLocation, "", "");
		overlay.setMarker(locationMarker);

		// replace previous overlay with the new one
		itemizedOverlay.updateNavOverlay(overlay);

		if (mapOverlays.isEmpty()) {
			// no markers on the map
			mapOverlays.add(itemizedOverlay);
		}

		// invalidate current map in order to force a redraw of the markers
		mapView.invalidate();
		// }

	}

	protected void onPostExecute(ArrayList<Route> result) {
		dialog.dismiss();
		if (result!=null) {
			updateUserLocationOverlay(userLocation);
			mController.animateTo(userLocation);
			if (result != null) {
				itemizedOverlay.clear();
				GeoPoint geoPoint = null;
				for (Route route : result) {
					int size = route.get_stopItems().size();
					StopItem[] stops = route.get_stopItems().values()
							.toArray(new StopItem[size]);
					for (StopItem stopItem : stops) {
						geoPoint = new GeoPoint((int) (stopItem.get_lat() * 1e6),
								(int) (stopItem.get_lon() * 1e6));
						itemizedOverlay.addOverlay(new RouteMapStopOverlayItem(
								geoPoint, stopItem.get_title(),
								"Tap to see predictions.", stopItem));
					}
				}
				itemizedOverlay.restoreNavOverlay();
				itemizedOverlay.populate_overlayItem();

				mController.setZoom(17);
				// UserLocationHandler.this.start(context)
				// mapView.invalidate();
			}

		}
				// Toast.makeText(context, nearByString, Toast.LENGTH_LONG).show();
	}

	

	

}
